<?php
namespace app\controller;

use think\facade\Queue;
use think\Cache;
use app\model\Order;
use app\model\SeckillActivity;
use app\model\SeckillOrder;
use app\model\Member;
use think\facade\Db;
use think\facade\Cache as CacheFacade;

class Seckill
{
    // 抢购接口
    public function seckill()
    {
        $activityId = input('activity_id/d', 0);
        $userId = input('user_id/d', 0); // 实际项目中应从登录信息获取

        // 验证活动是否存在且有效
        $activity = SeckillActivity::find($activityId);
        if (!$activity || strtotime($activity->start_time) > time() || strtotime($activity->end_time) < time()) {
            return json(['code' => 0, 'msg' => '活动不存在或已结束','data'=>$activity]);
        }

        // 检查用户是否已经参与过该活动
        if (SeckillOrder::where(['user_id' => $userId, 'activity_id' => $activityId])->find()) {
            return json(['code' => 0, 'msg' => '您已经参与过该活动']);
        }

        // 使用Redis原子操作防止重复提交
        $lockKey = "seckill:user:{$userId}:activity:{$activityId}";
        if (cache($lockKey)) {
            return json(['code' => 0, 'msg' => '请勿重复提交']);
        }else{
            cache($lockKey,1,60);
        }

        // 加入队列
        $jobData = ['user_id' => $userId, 'activity_id' => $activityId];
        $isPushed = Queue::push('app\job\SeckillJob', $jobData);

        if ($isPushed === false) {
            cache($lockKey,null);
            return json(['code' => 0, 'msg' => '抢购失败，请重试']);
        }

        return json(['code' => 1, 'msg' => '抢购中，请稍后查看结果']);
    }

    // 查询抢购结果
    public function result()
    {
        $activityId = input('activity_id/d', 0);
        $userId = input('user_id/d', 0);

        $order = SeckillOrder::where([
            'user_id' => $userId,
            'activity_id' => $activityId
        ])->find();

        if ($order) {
            return json(['code' => 1, 'msg' => '抢购成功', 'data' => $order]);
        }

        // 检查活动是否还有库存
        $activity = SeckillActivity::find($activityId);
        if ($activity && $activity->stock <= 0) {
            return json(['code' => 0, 'msg' => '抢购已结束']);
        }

        return json(['code' => 2, 'msg' => '抢购处理中']);
    }
    // 获取库存接口（优化版）
    public function stock()
    {
        $activityId = input('activity_id/d', 0);
        
        // 先从缓存获取库存
        $cacheKey = "seckill:stock:{$activityId}";
        $stock = CacheFacade::get($cacheKey);
        
        if ($stock) {
            return json([
                'code' => 1,
                'msg' => 'success',
                'data' => [
                    'stock' => $stock,
                    'activity' => $activityId,
                ]
            ]);
        }
        
        // 缓存不存在，从数据库获取
        $activity = SeckillActivity::find($activityId);

        if (!$activity) {
            return json(['code' => 0, 'msg' => '活动不存在']);
        }
        
        // 设置缓存，有效期5分钟
        CacheFacade::set($cacheKey, $activity->stock, 300);

        return json([
            'code' => 1,
            'msg' => 'success',
            'data' => [
                'stock' => $activity->stock,
                'activity' => $activity,
            ]
        ]);
    }
    
    // 获取秒杀活动列表
    public function list()
    {
        $page = input('page/d', 1);
        $pageSize = input('pageSize/d', 10);
        
        // 获取当前时间
        $now = date('Y-m-d H:i:s');
        
        // 查询进行中和即将开始的活动
        $activities = SeckillActivity::where('end_time', '>', $now)
            ->order('start_time', 'asc')
            ->paginate(['list_rows' => $pageSize, 'page' => $page]);
        
        $list = [];
        foreach ($activities as $activity) {
            // 判断活动状态
            $status = 0; // 未开始
            if (strtotime($activity->start_time) <= time()) {
                $status = 1; // 进行中
            }
            
            $list[] = [
                'id' => $activity->id,
                'goods_id' => $activity->goods_id,
                'start_time' => $activity->start_time,
                'end_time' => $activity->end_time,
                'price' => $activity->price,
                'stock' => $activity->stock,
                'status' => $status
            ];
        }
        
        return json([
            'code' => 1,
            'msg' => 'success',
            'data' => [
                'list' => $list,
                'total' => $activities->total(),
                'page' => $page,
                'pageSize' => $pageSize
            ]
        ]);
    }
    
    // 获取秒杀活动详情
    public function detail()
    {
        $activityId = input('activity_id/d', 0);
        $activity = SeckillActivity::find($activityId);
        
        if (!$activity) {
            return json(['code' => 0, 'msg' => '活动不存在']);
        }
        
        // 判断活动状态
        $status = 0; // 未开始
        if (strtotime($activity->start_time) <= time() && strtotime($activity->end_time) > time()) {
            $status = 1; // 进行中
        } elseif (strtotime($activity->end_time) <= time()) {
            $status = 2; // 已结束
        }
        
        // 获取商品信息（这里需要根据实际的goods表结构补充）
        $goods = Db::name('goods')->where('id', $activity->goods_id)->find();
        
        return json([
            'code' => 1,
            'msg' => 'success',
            'data' => [
                'id' => $activity->id,
                'goods_id' => $activity->goods_id,
                'goods_name' => $goods ? $goods['name'] : '',
                'original_price' => $goods ? $goods['price'] : 0,
                'start_time' => $activity->start_time,
                'end_time' => $activity->end_time,
                'price' => $activity->price,
                'stock' => $activity->stock,
                'status' => $status,
                'countdown' => $status == 0 ? strtotime($activity->start_time) - time() : 0
            ]
        ]);
    }
    
    // 优化的抢购接口
    public function optimizedSeckill()
    {
        $activityId = input('activity_id/d', 0);
        $userId = input('user_id/d', 0); // 实际项目中应从登录信息获取
        
        // 检查用户是否存在
        $member = Member::find($userId);
        if (!$member) {
            return json(['code' => 0, 'msg' => '用户不存在']);
        }

        // 验证活动是否存在且有效
        $activity = SeckillActivity::find($activityId);
        if (!$activity || strtotime($activity->start_time) > time() || strtotime($activity->end_time) < time()) {
            return json(['code' => 0, 'msg' => '活动不存在或已结束']);
        }
        
        // 检查商品是否存在
        $goods = Db::name('goods')->where('id', $activity->goods_id)->find();
        if (!$goods || $goods['stock'] <= 0) {
            return json(['code' => 0, 'msg' => '商品不存在或库存不足']);
        }

        // 检查用户是否已经参与过该活动
        if (SeckillOrder::where(['user_id' => $userId, 'activity_id' => $activityId])->find()) {
            return json(['code' => 0, 'msg' => '您已经参与过该活动']);
        }

        // 使用Redis原子操作防止重复提交
        $lockKey = "seckill:user:{$userId}:activity:{$activityId}";
        if (CacheFacade::get($lockKey)) {
            return json(['code' => 0, 'msg' => '请勿重复提交']);
        } else {
            CacheFacade::set($lockKey, 1, 60);
        }
        
        // 预减库存（Redis）
        $stockKey = "seckill:stock:{$activityId}";
        $stock = CacheFacade::get($stockKey);
        
        if ($stock === false) {
            // 缓存不存在，从数据库获取并设置缓存
            $stock = $activity->stock;
            CacheFacade::set($stockKey, $stock, 300);
        }
        
        if ($stock <= 0) {
            CacheFacade::delete($lockKey);
            return json(['code' => 0, 'msg' => '库存不足']);
        }
        
        // 原子递减库存
        $stock = CacheFacade::decr($stockKey);
        
        if ($stock < 0) {
            // 库存不足，回滚
            CacheFacade::incr($stockKey);
            CacheFacade::delete($lockKey);
            return json(['code' => 0, 'msg' => '库存不足']);
        }

        // 加入队列
        $jobData = ['user_id' => $userId, 'activity_id' => $activityId];
        $isPushed = Queue::push('app\job\SeckillJob', $jobData);

        if ($isPushed === false) {
            // 推送队列失败，回滚库存
            CacheFacade::incr($stockKey);
            CacheFacade::delete($lockKey);
            return json(['code' => 0, 'msg' => '抢购失败，请重试']);
        }

        return json(['code' => 1, 'msg' => '抢购中，请稍后查看结果']);
    }
}